<template>
    <!-- drag：表示支持拖拽上传；action：表示上传的地址；accept：接收上传的文件类型 -->
    <!-- before-upload: 上传文件之前的钩子，若返回 false 或者返回 Promise 且被 reject，则停止上传。 -->
    <!-- http-request: 覆盖默认的上传行为，可以自定义上传的实现 -->
    <el-upload class="upload-demo" drag action="#" accept=".xlsx, .xls" 
        :before-upload="beforeAvatarUpload" 
        :http-request="handleClick"
    >
        <i class="el-icon-upload"></i>
        <div>
            <el-button type="text" @click.stop="downloadTemplate">下载导入模版</el-button>
        </div>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">只能上传xlsx/xls文件，且不超过5MB</div>
    </el-upload>
</template>
<script>
import XLSX from 'xlsx'

export default {
    name: 'UploadExcel',
    props: {
        onSuccess: {
            type: Function,
            required: true
        },
        downloadTemplate: {
            type: Function,
            required: true
        }
    },
    data() {
        return {
            excelData: {
                header: null,
                results: null
            }
        }
    },
    methods: {
        // 上传文件之前的判断操作
        beforeAvatarUpload(file) {
            const isExcel = /\.(xlsx|xls|csv)$/.test(file.name)
            const isLt5M = file.size / 1024 / 1024 < 5;
            if (!isExcel) {
                this.$message.error('只能上传excel形式表格文件！')
            }
            if (!isLt5M) {
                this.$message.error('上传文件大小不能超过 5MB!')
            }
            return isExcel && isLt5M
        },
        // 上传行为
        handleClick(data) {
            this.readerData(data.file)
        },
        // 处理excel内容
        readerData(rawFile) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader()
                reader.onload = e => {
                    const data = e.target.result
                    const workbook = XLSX.read(data, { type: 'array' })
                    const firstSheetName = workbook.SheetNames[0]
                    const worksheet = workbook.Sheets[firstSheetName]
                    // 获取表头内容
                    const header = this.getHeaderRow(worksheet)
                    // 获取表格内容（包括表头和值）
                    const results = XLSX.utils.sheet_to_json(worksheet)
                    this.generateData({ header, results })
                    resolve()
                }
                reader.readAsArrayBuffer(rawFile)
            })
        },
        // 将解析好的内容交给onSuccess函数
        generateData({ header, results }) {
            this.excelData.header = header
            this.excelData.results = results
            this.onSuccess(this.excelData)
        },
        getHeaderRow(sheet) {
            const headers = []
            const range = XLSX.utils.decode_range(sheet['!ref'])
            let C
            const R = range.s.r
            /* start in the first row */
            for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
                const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
                /* find the cell in the first row */
                let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
                if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
                headers.push(hdr)
            }
            return headers
        }
    }
}
</script>
<style lang="scss">
.upload-demo {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    .el-upload-dragger {
        padding-top: 38px;
        border: 3px dashed #d9d9d9;
        width: 500px;
        height: 250px;
    }
}
</style>
